#include <stdlib.h>
#include <GL/glfw.h>
#include <iostream>

#define znear 1
#define zfar 2
void Init(void);
void Shut_Down(int return_code);
void Main_Loop(void);
void Draw_Square(float red, float green, float blue, float x, float y, float width);
void Draw_Line(float red, float green, float blue, float x1, float y1,float x2, float y2, float width);
void SetView(void);
void FPS(void);
void CheckKeys(void);
 
float zoom = 1,
    xpos = 0,
	ypos = 0,
	drag_x = 0,
	drag_y = 0,
	fleft = -1,
	fright = 1,
	ftop = 1,
	fbottom = -1,
	aspect_ratio = 1;
const int window_width = 600,
		  window_height = 800;
 
  double old_time = 0;
  double acc_time = 0; //keep track of accumulated time so we can display FPS
  int frames = 0; //keep track of frames in a second
int main(void)
{
  Init();
  Main_Loop();
  Shut_Down(0);
}
 
void Init(void)
{
  
 
  if (glfwInit() != GL_TRUE)
    Shut_Down(1);
  // 800 x 600, 16 bit color, no depth, alpha or stencil buffers, windowed
  if (glfwOpenWindow(window_width, window_height, 5, 6, 5, 0, 0, 0, GLFW_WINDOW) != GL_TRUE)
	Shut_Down(1);
	glfwSetWindowTitle("PICTOSS");

	// set the projection matrix to a normal frustum with a max depth of 5000 (to allow for zooming really far out), min of 1 (really close in zoom....)
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	aspect_ratio = ((float)window_height) / window_width;
	ftop = -(fright-fleft)/2*aspect_ratio;
	fbottom = -ftop;
	glFrustum(fleft, fright, ftop, fbottom, znear, zfar);
	glMatrixMode(GL_MODELVIEW);
	glTranslatef(0, 0, -1);

	// the time of the first frame
	old_time = glfwGetTime();
}
 
void Shut_Down(int return_code)
{
  glfwTerminate();
  exit(return_code);
}

void Main_Loop(void){
	while(1){
		SetView();
		CheckKeys();
		FPS();
		Draw_Square(1, 0, 0,-.5,-.5,1);
		Draw_Line(0,1,0,-1,-1,1,1,.05);
		for (float i = 0; i <= 110; i+=10){
			Draw_Line(0,1,0,0,i/10,8.5,i/10,.02);

		}
		for (float i = 0; i <= 85; i+=10){
			Draw_Line(0,1,0,i/10,0,i/10,11,.02);

		}
		// swap back and front buffers(display the frame)
		glfwSwapBuffers();
	}

}

void FPS(){
	glfwSleep(.015);//temporary! add a delay so we aren't using up all the CPU, and because we dont need 4000FPS...
	// calculate time elapsed, and the amount by which stuff rotates
	double current_time = glfwGetTime();
		
	//*******************Output current FPS**************************************//
		acc_time+=(current_time-old_time);
		frames++;
		if (acc_time>=1){
			std::cout<<frames<<" FPS | "<<xpos<<" = xpos   |   "<<ypos<<" = ypos   |   "<<fright<<" = fright   |   "<<ftop<<" = ftop"<<std::endl;
			acc_time = 0;
			frames = 0;
		}
		old_time = current_time;
	//****************************************************************************//
}
 
void CheckKeys(void){
	// escape to quit, arrow keys to zoom view
    if (glfwGetKey(GLFW_KEY_ESC) == GLFW_PRESS)
		Shut_Down(0);
	int mousex = 0, mousey = 0;
	glfwGetMousePos(&mousex, &mousey);
    if (glfwGetKey(GLFW_KEY_LEFT) == GLFW_PRESS){
		//account for mouse position (zoom out towards mouse)
		xpos = ((((float)mousex+.5)/window_width)*(fright-fleft))+fleft;
		ypos = ((((float)mousey+.5)/window_height)*(ftop-fbottom))+fbottom;
		zoom = 1.25;
	}
    if (glfwGetKey(GLFW_KEY_RIGHT) == GLFW_PRESS){
		//account for mouse position (zoom in centered on mouse)
		xpos = ((((float)mousex+.5)/window_width)*(fright-fleft))+fleft;
		ypos = ((((float)mousey+.5)/window_height)*(ftop-fbottom))+fbottom;
		zoom =.8;

	}
}

void Draw_Line(float red, float green, float blue, float x1, float y1, float x2, float y2, float width){
	glDisable(GL_TEXTURE_2D); 
    glEnable(GL_BLEND); 
	glColor3f(red, green, blue);
	glLineWidth(width); 
    glBegin(GL_LINES); 
    glVertex2i( x1, y1); 
    glVertex2i( x2, y2); 
    glEnd(); 

    glDisable(GL_BLEND); 
    glEnable(GL_TEXTURE_2D); 
}
void Draw_Square(float red, float green, float blue,float x,float y,float width)
{
	glColor3f(red, green, blue);
	glRectf(x,y, x+width, y+width);
}
 
void SetView(void)
{
	// clear the buffer
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
	// reset view matrix
	glLoadIdentity();

	//zoom, while recentering on the cursor position
	//reset the far plane location
	double _width = fright-fleft;
	double _height = ftop-fbottom;
	fleft=xpos-(xpos-fleft)/zoom;
	fright=fleft+_width/zoom;
	ftop=ypos-(ypos-ftop)/zoom;
	fbottom=ftop-_height/zoom;
	glFrustum( fleft,fright,ftop/aspect_ratio, fbottom/aspect_ratio, znear, zfar);
	glTranslatef(0, 0, -1);
	//set the zoom to 1 so it doesnt keep zooming in/out
	zoom=1;
	//Zoom complete
	

	int squares = 16;
	float red = 0, blue = 1;
	Draw_Square(red, .6, blue,0,0,.5);
}